#ifndef BM_OBJ_H
#define BM_OBJ_H
#ifdef __APPLE__
    #include <SDL/SDL.h>
#else
    #include <SDL/SDL.h>
#endif
#include "../BM_anitex.h"
#include <vector>
#include "SmVR_CObjFromFile.h" // virtual base class

/* Black Voltage team did not code this OBJ loader. We have improved & modified it but we haven't coded it! We take no credits. */

using namespace std;

typedef struct {
    float x, y, z;
} TVertices;

typedef struct {
    int v[3];       // vertex index
    int normal[3];  // normal index for each vertex
    int texture[3]; // texture index for each vertex
} TFaces;

typedef struct {
    float r, g, b;
} TRGB;

typedef struct {
    char Name[200], TextureName[200];
    BMTex TextObj;
    TRGB dif, spe, amb;
    float Ns, d, illum;
    bool flag;
} TMaterial;

typedef struct {
    int FirstFace, LastFace, Mat;
    char MaterialName[200];
} TFacesMat;

class BMOBJ : public SmVR_CObjFromFile {
    public:
        static void extract_file_path(char *nome_arq, char *buf); // buf recebe o caminho de nome_arq

        BMOBJ();
        virtual ~BMOBJ();
        void freeOBJ();

        vector<TVertices*> GetVertices();
        vector<TFaces*> GetFaces();
        vector<TFacesMat*> GetFacesWithMaterials();
        vector<TVertices*> GetFaceNormals();
        vector<TVertices*> GetVertexTextures();
        vector<TVertices*> GetVertexNormals();
        vector<TMaterial*> GetMaterials();
        //RAPID_model* GetCollisionModel();
        char* GetFileName();
        void GetBoundaries(SmVR_CPoint *min, SmVR_CPoint *max);

        void InvertNormalOrientation(void);
        //int Collided(SmVR_CObjFromFile *obj, SmVR_Matrix mtx1, SmVR_Matrix mtx2, int mode);
        int loadOBJ(char *filename);
        void drawOBJ();
        void moveOBJ(float in_x, float in_y, float in_z);
        void reloadTextures();
        void printfObject(int v = 1, int f = 1, int fwm = 1, int fn = 1, int vt = 1, int vn = 1, int m = 1);
        float getX();
        float getY();
        float getZ();
    protected:
        int NormalOrientation;
        char Name[200]; // O nome do arquivo .obj carregado
        //RAPID_model collisionModel;
        TVertices Min, Max;
        vector<TVertices*> Vertices;
        vector<TFaces*> Faces;
        vector<TFacesMat*> FacesWithMaterials;
        vector<TVertices*> FaceNormals;
        vector<TVertices*> VertexTextures;
        vector<TVertices*> VertexNormals;
        vector<TMaterial*> Materials;

        //void RAPID_model_Read();
                                       // SVE matrix, rotation matrix, translation matrix
        void SmVR_RAPIDMatrixConversion(SmVR_Matrix M_SmVR, double MR[3][3], double MT[3]);
        TVertices CalculateNormal(TVertices *v1, TVertices *v2, TVertices *v3);
        void ReadALine(FILE *infile, char buff[2000]);
        void TryToGetMaterialParameterStr(char *line, char *parameter, char *str);
        void TryToGetMaterialParameterRGB(char *line, char *parameter, TRGB &color);
        void TryToGetMaterialParameterFloat(char *line, char *parameter, float &value);
        void ProcessMaterial(FILE *MatFile, char *line);
        void ReadMaterialFile(char *MaterialLibraryName);
        int SearchForMaterialNumber(char *MaterialName);
    private:
        float x, y, z;
};

#endif //END BM_OBJ_H
